package daydayup.gateway;


import java.util.concurrent.ConcurrentHashMap;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;

public class ElasticSimpleJob implements SimpleJob {
	
	private int i = 1;
	/**
	 * ThreadLocal，很多地方叫做线程本地变量，也有些地方叫做线程本地存储，其实意思差不多。
	 * 可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本，那么每个线程可以访问自己内部的副本变量。
	 */
	private ThreadLocal<Integer> threadlocal = new ThreadLocal<Integer>();
	/**
	 * 这儿为本人见解
	 * threadLocal中存储的变量的副本，当为基本变量时，就是改值得副本；当为引用时则为不同对象的引用，只是引用的名字相同而已；
	 * 但是ThreadLocal取值时，并没有用引用直接取值，而是用的自身即this，所以他们就是不一样的了。
	 */
	
	/**
	 * ConcurrentHashMap在JDK8中进行了巨大改动，很需要通过源码来再次学习下Doug Lea的实现方法。
	       它摒弃了Segment（锁段）的概念，而是启用了一种全新的方式实现,利用CAS算法。它沿用了与它同时期的HashMap版本的思想，
	       底层依然由“数组”+链表+红黑树的方式思想(JDK7与JDK8中HashMap的实现)，但是为了做到并发，又增加了很多辅助的类，
	       例如TreeBin，Traverser等对象内部类。
	 */
	private ConcurrentHashMap<String, Integer> currentMap = new  ConcurrentHashMap<>();
	
	/**
	 * 对于HashMap初始容量大小的设置
	 * 通常，默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销，但同时也增加了查询成本
	 * （在大多数 HashMap 类的操作中，包括 get 和put 操作，都反映了这一点）。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子，
	 * 以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子，则不会发生 rehash 操作。
	 * 以上就是在创建hashmap设置初始大小时候的原则。
	 * 
	 * 如果x=100，那么HashMap的初始大小应该是128.但是100/128=0.78，已经超过默认加载因子的大小了。因此会resize一次，变成256。
	 * 所以最好的结果还是256。
	 */

	@Override
	public void execute(ShardingContext arg0) {
		
		new Thread(new Runnable() {

			@Override
			public void run() {
				
				try {
						
						i =i+1;
						
						threadlocal.set(i);
						currentMap.put(Thread.currentThread().getName(), i);
						
						System.out.println("ThreadLocal======前" + Thread.currentThread().getName() + "========" + threadlocal.get());
						System.out.println("ConcurrentHashMap=====前" +Thread.currentThread().getName() + "=====" + currentMap.get(Thread.currentThread().getName()));
						
						Thread.sleep(1000);
						
						System.out.println("ThreadLocal======后" + Thread.currentThread().getName() + "========" + threadlocal.get());
						System.out.println("ConcurrentHashMap=====后" +Thread.currentThread().getName() + "====="  + currentMap.get(Thread.currentThread().getName()));
					
						//Thread.currentThread().
						
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		}).start();
		
	}

}
